package main

import (
	"log"
)

/*
func main() {
	var lists []int
	for n:=1; n<=40000; n++{
		for m:=2;m<n; m++ {
			if n % m != 0 {
				if n - m == 1 {
					lists = append(lists, n)
				}
				continue
			}
			break
		}
	}
	fmt.Println(lists)
}
 */
// 求1~200000的素数
// 1. 开启一个协程  一个channel1 放入数字
// 2. 启动四个协程从channel1取值 统计数字， 再开启一个channel放入统计的数据。
// 3. 每个线程任务执行完放入一个key到channel3，
// 4. 主线程for循环去读channel3，读出四个值就确定channel2计算完了。

func saveNum(numChan chan int, num int)  {
	// 放值
	for i := 1; i <= num; i++ {
		numChan <- i
	}
	// 因为一个协程，所以关闭管道
	close(numChan)
}

func saveSuShu(numChan chan int, suShuChan chan int, exitChan chan bool) {
	for true {
		nu, ok := <- numChan
		if !ok{
			// 取不到值退出
			break
		}
		// 默认就是素数
		flag := true
		for i:=2; i<nu; i++ {
			if nu % i == 0{
				flag = false
				break
			}
		}
		// 如果循环下来flag还是true，则这个数为素数，并写到素数的管道里面
		if flag{
			suShuChan <- nu
		}
	}
	// 无法确定另外三个线程是否还在使用channel，则不关闭numChan
	log.Println("一个线程已经退出了。。。。")

	exitChan <- true
}

func main() {
	//1. 先定义一个存放1-8000数的管道
	numChan := make(chan int, 1000)
	//2. 定义一个存放素数的管道
	suShuChan := make(chan int, 3000)
	//3. 定义一个存放四个协程执行完退出指令的channel
	exitChan := make(chan bool, 4)

	num :=1000
	go saveNum(numChan, num)

	for i := 1; i <= 4; i++ {
		go saveSuShu(numChan, suShuChan, exitChan)
	}
	/*
	// 判断是否处理完素数，要对exitChan进行判断
	go func() {
		for c:=1;c<=4;c++{
			<- exitChan
		}
		// 四个则关闭channel
		close(suShuChan)
	}()
	for c:=1;c<=4;c++{
		<- exitChan
	}
	// 四个则关闭channel
	close(suShuChan)
	*/

	for true {
		if len(exitChan) == 4{
			close(suShuChan)
			break
		}
	}

	for true {
		re, ok := <-suShuChan
		if !ok {
			break
		}
		log.Printf("素数 = %v", re)
	}
	log.Println("main 协程退出。。。")
}
